#ifndef _SPELL_H_
#define _SPELL_H_ 1
#include "environ.h"
#include "strategy.h"
#include "command.h"
#include <string>
#include <vector>
#include <iostream>
#include <sstream>
class StrategyFactory{
public:
  StrategyFactory(Environ *environ,std::string lexicon_dir):environ(environ){
    ENG_LEXICON = lexicon_dir + ENG_LEXICON;
    FRA_LEXICON = lexicon_dir + FRA_LEXICON;
  }
  ~StrategyFactory() = default;
  LangStrategy *
  create_lang_strategy();
  FormatStrategy * 
  create_format_strategy();
private:
  Environ *environ;
  std::string ENG_LEXICON = "/eng.txt";
  std::string FRA_LEXICON = "/fra.txt";
  class CGarbo{  
    public:  
        ~CGarbo()  
        {  
            LocalStrategy::destroy_instance();
            TXTStrategy::destroy_instance();
            XMLStrategy::destroy_instance();
        }  
  };  
  static CGarbo Garbo;  
};
class SpellChecker{
public:
  SpellChecker(StrategyFactory * sf):sf(sf){
  }
  ~SpellChecker();
  std::vector<std::string> 
  spell(std::string context);
private:
  StrategyFactory *sf;
};
class SPCommand:public Command{
public:
  SPCommand(std::string str,Editor *editor,SpellChecker *sc):Command(str,editor),sc(sc){
  };
  inline std::string  
  execute(){
    std::string result;
    std::vector<std::string> faults = sc->spell(editor->get_text());
    for(auto &str:faults)
      result += str + "\n";
    return result;
  };
private:
  SpellChecker *sc;
};
class SPACommand:public Command{
public:
  SPACommand(std::string str,Editor *editor,SpellChecker *sc):Command(str,editor),sc(sc){
  };
  std::string 
  execute();
private:
  SpellChecker *sc;
};
class SPMCommand:public ModifiedCommand{
public:
  SPMCommand(std::string str,Editor *editor,SpellChecker *sc):ModifiedCommand(str,editor),sc(sc){
  };
  void 
  edit();
private:
  SpellChecker *sc;
};
#endif
